import { useParams } from 'common'
import dayjs from 'dayjs'
import { ArrowRight, LogsIcon, RefreshCw } from 'lucide-react'
import { useRouter } from 'next/router'
import { parseAsJson, useQueryState } from 'nuqs'
import { useState } from 'react'
import ReportFilterBar from '@/components/interfaces/Reports/ReportFilterBar'
import ReportHeader from '@/components/interfaces/Reports/ReportHeader'
import ReportPadding from '@/components/interfaces/Reports/ReportPadding'
import { REPORT_DATERANGE_HELPER_LABELS } from '@/components/interfaces/Reports/Reports.constants'
import ReportStickyNav from '@/components/interfaces/Reports/ReportStickyNav'
import { SharedAPIReport } from '@/components/interfaces/Reports/SharedAPIReport/SharedAPIReport'
import { useSharedAPIReport } from '@/components/interfaces/Reports/SharedAPIReport/SharedAPIReport.constants'
import { ReportChartV2 } from '@/components/interfaces/Reports/v2/ReportChartV2'
import { ReportSectionHeader } from '@/components/interfaces/Reports/v2/ReportSectionHeader'
import {
numericFilterSchema,
ReportsNumericFilter,
} from '@/components/interfaces/Reports/v2/ReportsNumericFilter'
import {
ReportsSelectFilter,
selectFilterSchema,
} from '@/components/interfaces/Reports/v2/ReportsSelectFilter'
import { LogsDatePicker } from '@/components/interfaces/Settings/Logs/Logs.DatePickers'
import UpgradePrompt from '@/components/interfaces/Settings/Logs/UpgradePrompt'
import DefaultLayout from '@/components/layouts/DefaultLayout'
import ObservabilityLayout from '@/components/layouts/ObservabilityLayout/ObservabilityLayout'
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
import type { ChartHighlightAction } from '@/components/ui/Charts/ChartHighlightActions'
import { ReportSettings } from '@/components/ui/Charts/ReportSettings'
import { ObservabilityLink } from '@/components/ui/ObservabilityLink'
import {
createErrorsReportConfig,
createLatencyReportConfig,
createUsageReportConfig,
} from '@/data/reports/v2/auth.config'
import { useRefreshHandler, useReportDateRange } from '@/hooks/misc/useReportDateRange'
import type { NextPageWithLayout } from '@/types'
const AuthReport: NextPageWithLayout = () => {
return (
)
}
AuthReport.getLayout = (page) => (
{page}
)
export type UpdateDateRange = (from: string, to: string) => void
export default AuthReport
const AuthUsage = () => {
const { ref } = useParams()
const chartSyncId = `auth-report`
const {
selectedDateRange,
updateDateRange,
datePickerValue,
datePickerHelpers,
showUpgradePrompt,
setShowUpgradePrompt,
handleDatePickerChange,
} = useReportDateRange(REPORT_DATERANGE_HELPER_LABELS.LAST_60_MINUTES)
const {
data,
error,
isLoading,
refetch,
isRefetching,
filters,
addFilter,
removeFilters,
isLoadingData,
sql,
} = useSharedAPIReport({
filterBy: 'auth',
start: selectedDateRange?.period_start?.date,
end: selectedDateRange?.period_end?.date,
})
const [isRefreshing, setIsRefreshing] = useState(false)
const [monitoringStatusCodeFilter, setMonitoringStatusCodeFilter] = useQueryState(
'monitoring_status_code',
parseAsJson(numericFilterSchema.parse)
)
const [usageProviderFilter, setUsageProviderFilter] = useQueryState(
'usage_provider',
parseAsJson(selectFilterSchema.parse)
)
const providerOptions = [
{ label: 'Email', value: 'email' },
{ label: 'Google', value: 'google' },
{ label: 'Apple', value: 'apple' },
{ label: 'Phone', value: 'phone' },
{ label: 'Discord', value: 'discord' },
{ label: 'Azure', value: 'azure' },
{ label: 'GitHub', value: 'github' },
{ label: 'Kakao', value: 'kakao' },
{ label: 'TOTP', value: 'totp' },
{ label: 'Twitter', value: 'twitter' },
{ label: 'SAML', value: 'saml' },
{ label: 'Recovery', value: 'recovery' },
{ label: 'SSO/SAML', value: 'sso/saml' },
{ label: 'Magic Link', value: 'magiclink' },
{ label: 'Keycloak', value: 'keycloak' },
{ label: 'Facebook', value: 'facebook' },
{ label: 'Twitch', value: 'twitch' },
{ label: 'LinkedIn OIDC', value: 'linkedin_oidc' },
{ label: 'Spotify', value: 'spotify' },
{ label: 'Email Change', value: 'email_change' },
{ label: 'Snapchat', value: 'snapchat' },
{ label: 'WorkOS', value: 'workos' },
{ label: 'Notion', value: 'notion' },
{ label: 'Slack OIDC', value: 'slack_oidc' },
{ label: 'Figma', value: 'figma' },
{ label: 'GitLab', value: 'gitlab' },
{ label: 'LinkedIn', value: 'linkedin' },
{ label: 'Zoom', value: 'zoom' },
]
const usageReportConfig = createUsageReportConfig({
projectRef: ref || '',
startDate: selectedDateRange?.period_start?.date,
endDate: selectedDateRange?.period_end?.date,
interval: selectedDateRange?.interval,
filters: { provider: usageProviderFilter },
})
const errorsReportConfig = createErrorsReportConfig({
projectRef: ref || '',
startDate: selectedDateRange?.period_start?.date,
endDate: selectedDateRange?.period_end?.date,
interval: selectedDateRange?.interval,
filters: { status_code: monitoringStatusCodeFilter },
})
const latencyReportConfig = createLatencyReportConfig({
projectRef: ref || '',
startDate: selectedDateRange?.period_start?.date,
endDate: selectedDateRange?.period_end?.date,
interval: selectedDateRange?.interval,
filters: {},
})
const onRefreshReport = useRefreshHandler(
datePickerValue,
datePickerHelpers,
handleDatePickerChange,
async () => {
if (!selectedDateRange) return
setIsRefreshing(true)
refetch()
setTimeout(() => setIsRefreshing(false), 1000)
}
)
const router = useRouter()
const highlightActions: ChartHighlightAction[] = [
{
id: 'api-gateway-logs',
label: 'Open in API Gateway Logs',
icon: ,
onSelect: ({ start, end, chartId }) => {
let url = `/project/${ref}/logs/edge-logs?its=${start}&ite=${end}`
if (chartId?.includes('errors')) {
url += `&f={"product":{"auth":true},"status_code":{"error":true,"warning":true}}`
} else {
url += `&f={"product":{"auth":true}}`
}
router.push(url)
},
},
{
id: 'auth-logs',
label: 'Open in Auth Logs',
icon: ,
onSelect: ({ start, end }) => {
const url = `/project/${ref}/logs/auth-logs?its=${start}&ite=${end}`
router.push(url)
},
},
]
return (
<>
}
className="w-7"
tooltip={{ content: { side: 'bottom', text: 'Refresh report' } }}
onClick={onRefreshReport}
/>
{selectedDateRange && (
{dayjs(selectedDateRange.period_start.date).format('MMM D, h:mma')}
{dayjs(selectedDateRange.period_end.date).format('MMM D, h:mma')}
)}
}
>
{usageReportConfig.map((metric) => (
))}
{errorsReportConfig.map((metric) => (
))}
>
)
}